/**
 * BlockTestCase.m
 *
 * Revision History: 
 *
 * Date     Author       Version   Changes
 * ======== ============ ========= ================================================================
 * 04/10/10 Steve Hu     3.0       Initial version.
 * 04/11/10 Steve Hu	 3.1	   Add one sample test for each of the testIntialBlockValues,
 *                                 testBlockType and testBlockMovement methods.
 * 04/11/10 Judy Cheng   3.2       Add level 3 and 5 for testBlockType, moveRight moveLeft moveUp 
 *								   for testBlockMovement.
 * ======== ============ ========= =================================================================
 *
 */

#import "BlockTestCase.h"


@implementation BlockTestCase

/* This method test the block's intial values are set properly.  */
- (void) testInitialBlockValues
{
	testBlock = [[Block newBlock: 1] retain];
	/* Make sure Object is create successfully first.  */
	STAssertNotNil(testBlock, @"Could not create testBlock subject.");
	
	STAssertTrue([testBlock boardX] == 0 && [testBlock boardY] == 0,
				 @"Block should be initiated at coordinate (0, 0), but was at (%d, %d).",
				 [testBlock boardX], [testBlock boardY]);
	
	STAssertEquals(NO, [testBlock stuck],
				   @"Block should not be stuck in the beginning.");
	
	STAssertEquals(NO, [testBlock disappearing],
				   @"Block should not be disappearing in the beginning.");
	
	STAssertEquals(255,(int) testBlock.opacity,
				   @"Block opacity should be 255 in the beginning, but was %d.", testBlock.opacity);
	[testBlock release];
}

/* This method test the randomly generated block type number is within the range acoording to the 
   difficulty level.  */
- (void) testBlockType 
{
	/* Test the random generated block range number is between 1 t 5 five times in level 1. */
	int level = 1;
	for (int i = 0; i < 5; i++)
	{
		testBlock = [[Block newBlock:(int) level] retain];
		/* Make sure Object is create successfully first.  */
		STAssertNotNil(testBlock, @"Could not create testBlock subject.");
		int blocktype = [testBlock BlockType];
		
		/* Check the block range.  */
		STAssertTrue(blocktype >= 1 && blocktype <= 5,
				 @"In level %d, block number should range from 1 to 5, but the number was %d.", 
					 level, blocktype);
		[testBlock release];
	}
	
	/* Test the random generated block range number is between 0 to 5 five times in level 2. */
	level = 2;
	for (int i = 0; i < 5; i++)
	{
		testBlock = [[Block newBlock:(int) level] retain];
		/* Make sure Object is create successfully first.  */
		STAssertNotNil(testBlock, @"Could not create testBlock subject.");
		int blocktype = [testBlock BlockType];
		
		/* Check the block range.  */
		STAssertTrue(blocktype >= 0 && blocktype <= 5,
					 @"In level %d, block number should range from 0 to 5, but the number was %d.", 
					 level, blocktype);
		[testBlock release];
	}
	
	/* Test the random generated block range number is between 0 to 5 five times in level 3. */
	level = 3;
	for (int i = 0; i < 5; i++)
	{
		testBlock = [[Block newBlock:(int) level] retain];
		/* Make sure Object is create successfully first.  */
		STAssertNotNil(testBlock, @"Could not create testBlock subject.");
		int blocktype = [testBlock BlockType];
		
		/* Check the block range.  */
		STAssertTrue(blocktype >= 0 && blocktype <= 5,
					 @"In level %d, block number should range from 0 to 5, but the number was %d.", 
					 level, blocktype);
		[testBlock release];
	}
	
	/* Test the random generated block range number is between 0 to 5 five times in level 4. */
	level = 4;
	for (int i = 0; i < 5; i++)
	{
		testBlock = [[Block newBlock:(int) level] retain];
		/* Make sure Object is create successfully first.  */
		STAssertNotNil(testBlock, @"Could not create testBlock subject.");
		int blocktype = [testBlock BlockType];
		
		/* Check the block range.  */
		STAssertTrue(blocktype >= 0 && blocktype <= 5,
					 @"In level %d, block number should range from 0 to 5, but the number was %d.", 
					 level, blocktype);
		[testBlock release];
	}
	
	/* Test the random generated block range number is between -4 to 5 and X five times in level 5 to 10. */
	for(int i = 5; i < 11; i++)
	{
		level = i;
		for (int i = 0; i < 5; i++)
		{
			testBlock = [[Block newBlock:(int) level] retain];
			/* Make sure Object is create successfully first.  */
			STAssertNotNil(testBlock, @"Could not create testBlock subject.");
			int blocktype = [testBlock BlockType];
			
			/* Check the block range.  */
			STAssertTrue(blocktype >= -4 && blocktype <= 5 ||blocktype == 10,
						 @"In level %d, block number should range from -4 to 5 and X, but the number was %d.", 
						 level, blocktype);
			[testBlock release];
		}
	}
}

/* This methods test the behaviours of the moveDown, moveUp, moveLeft, and moveRight methods.
   In our board coordinate system, moveDown and moveRight should result in moving the block
   +1 unit direction.  Otherwise, result in moving the block -1 unit direction.*/
- (void) testBlockMovement
{
	testBlock = [[Block newBlock: 1] retain];
	STAssertNotNil(testBlock, @"Could not create testBlock subject.");
	
	/* Move the test block 1 unit down in y direction.  */
	testBlock.moveDown;
	int testX = [testBlock boardX];
	int testY = [testBlock boardY];
	STAssertTrue(testX == 0 && testY == 1, 
				 @"Block should be located in (0, 1), but was at (%d, %d).", 
				 testX, testY);	
	
	/* Move the test block 1 unit down in x direction.  */
	testBlock.moveRight;
	testX = [testBlock boardX];
	testY = [testBlock boardY];
	STAssertTrue(testX == 1 && testY == 1, 
				 @"Block should be located in (1, 1), but was at (%d, %d).", 
				 testX, testY);	
	
	/* Move the test block 1 unit up in y direction.  */
	testBlock.moveUp;
	testX = [testBlock boardX];
	testY = [testBlock boardY];
	STAssertTrue(testX == 1 && testY == 0, 
				 @"Block should be located in (1, 0), but was at (%d, %d).", 
				 testX, testY);		
	
	/* Move the test block 1 unit left in y direction.  */
	testBlock.moveLeft;
	testX = [testBlock boardX];
	testY = [testBlock boardY];
	STAssertTrue(testX == 0 && testY == 0, 
				 @"Block should be located in (0, 0), but was at (%d, %d).", 
				 testX, testY);	
	

	[testBlock release];
}




@end
